package com.leessy.r229.server.http

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import android.util.Log
import com.alibaba.sdk.android.oss.*
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider
import com.alibaba.sdk.android.oss.model.GetObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.EncryptUtils
import com.blankj.utilcode.util.FileIOUtils
import com.google.gson.annotations.SerializedName
import com.leessy.r229.App
import com.leessy.r229.constants.Constants
import com.leessy.r229.kt.fromJson
import com.leessy.r229.kt.toJsonString

/**
 * @author : Created by liucheng. on 2021/7/1
 * @description : -
 */
object OssServerUtil {
    private val TAG = "Test------OSS "
    private val oss: OSS

    fun createFileName(fileName: String): String {
        return "AndroidLog/${Constants.SN}/$fileName"
    }

    init {
        val endpoint = "http://oss-cn-shenzhen.aliyuncs.com"
        //该配置类如果不设置，会有默认配置，具体可看该类
        val conf = ClientConfiguration()
        conf.connectionTimeout = 5 * 1000 // 连接超时，默认15秒
        conf.socketTimeout = 5 * 1000 // socket超时，默认15秒
        conf.maxConcurrentRequest = 5 // 最大并发请求数，默认5个
        conf.maxErrorRetry = 1 // 失败后最大重试次数，默认2次
        //这个开启会支持写入手机sd卡中的一份日志文件位置在SDCard_path\OSSLog\logs.csv
//        if (BuildConfig.DEBUG) OSSLog.enableLog() else OSSLog.disableLog()
        val pr =
            OSSAuthCredentialsProvider("${Constants.BaseURL}/api/Device/osssts?devicesn=${LoadTask.creatRequesSerialNo()}")
        pr.setDecoder {
            Log.d(TAG, "oss 服务器数据:  $it")
            try {
                val content = Base64.decode(it, Base64.NO_WRAP)
                val key = "e10adc3949ba59abbe56e057f20f883eecc6765474bb441a"
                val bs = EncryptUtils.decrypt3DES(
                    content,
                    ConvertUtils.hexString2Bytes(key),
                    "DESede/ECB/NoPadding",
                    null
                )
                val contentStr = String(bs, charset("GBK"))
                Log.d(TAG, "data2 = : ${contentStr}")
//                val contentStr = String(bs, charset("GBK"))
                //防止格式不正确这里解析
                val fromJson = contentStr.fromJson(OssBean::class.java) ?: OssBean()
                val toJsonString = fromJson.toJsonString()
                Log.d(TAG, "oss 参数: $toJsonString ")
                return@setDecoder toJsonString
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return@setDecoder OssBean().toJsonString()
        }
        oss = OSSClient(App.app, endpoint, pr, conf)
    }

    class OssBean {
        @SerializedName(value = "SecurityToken", alternate = ["securityToken"])
        var SecurityToken = ""

        @SerializedName(value = "Expiration", alternate = ["expiration"])
        var Expiration = ""

        @SerializedName(value = "AccessKeySecret", alternate = ["accessKeySecret"])
        var AccessKeySecret = ""

        @SerializedName(value = "AccessKeyId", alternate = ["accessKeyId"])
        var AccessKeyId = ""

        @SerializedName(value = "ErrorCode", alternate = ["errorCode"])
        var ErrorCode = 0

        @SerializedName(value = "ErrorMessage", alternate = ["errorMessage"])
        var ErrorMessage = ""

        @SerializedName(value = "StatusCode", alternate = ["statusCode"])
        var StatusCode = 0
    }

    fun putObject(fileName: String, file: String) = oss.putObject(createPut(fileName, file))
//    fun putObject(fileName: String, bmp: Bitmap) = oss.putObject(createPut(fileName, bmp))
//    fun putObject(fileName: String, bytes: ByteArray) = oss.putObject(createPut(fileName, bytes))
//    fun asyncPutObject(fileName: String, bmp: Bitmap, action: (Boolean) -> Unit) =
//        asyncPutObject(createPut(fileName, bmp), action)
//
//    fun asyncPutObject(fileName: String, bytes: ByteArray, action: (Boolean) -> Unit) =
//        asyncPutObject(createPut(fileName, bytes), action)

    private fun asyncPutObject(r: PutObjectRequest, action: (Boolean) -> Unit) {
        oss.asyncPutObject(
            r,
            object : OSSCompletedCallback<PutObjectRequest, PutObjectResult> {
                override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult?) {
                    Log.d(
                        TAG,
                        "成功********onSuccess() called with: request = $request, result = $result"
                    )
                    action(true)
                }

                override fun onFailure(
                    request: PutObjectRequest?,
                    clientException: ClientException?,
                    serviceException: ServiceException?
                ) {
                    action(false)
                    Log.d(
                        TAG,
                        "失败********onFailure() called with: request = $request, clientException = $clientException, serviceException = $serviceException"
                    )
                }
            })
    }


    private fun createPut(fileName: String, file: String): PutObjectRequest {
        return PutObjectRequest(
            Constants.bucketName,
            fileName,
            FileIOUtils.readFile2BytesByMap(file)
        )
    }


    fun uploadFileOss() {
        Log.d("ossTAG", "uploadFileOss: 开始上传")
        val decodeFile = BitmapFactory.decodeFile("/sdcard/HPTCloud/Record/1625045179191.jpg")
        val put = PutObjectRequest(
            "devicesnip",
            "测试目录/测试文件/test_upload_iamge2222中文.jpg",
            ConvertUtils.bitmap2Bytes(decodeFile, Bitmap.CompressFormat.JPEG, 100)
        )

        try {
//        val doesObjectExist = oss.doesObjectExist("devicesnip",
//                "测试目录/测试文件/test_upload_iamge2222中文.jpg")
//        Log.d("ossTAG", "uploadFileOss: 检查文件是否存在  $doesObjectExist")

//            val putObject = oss.putObject(put)
//            Log.d(TAG, "uploadFileOss: 请求结果 ${putObject.toJsonString()}")
            val asyncPutObject = oss.asyncPutObject(
                put,
                object : OSSCompletedCallback<PutObjectRequest, PutObjectResult> {
                    override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult?) {
                        Log.d(
                            "ossTAG",
                            "成功********onSuccess() called with: request = $request, result = $result"
                        )
                    }

                    override fun onFailure(
                        request: PutObjectRequest?,
                        clientException: ClientException?,
                        serviceException: ServiceException?
                    ) {
                        Log.d(
                            "ossTAG",
                            "失败********onFailure() called with: request = $request, clientException = $clientException, serviceException = $serviceException"
                        )
                    }
                })
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}